﻿



namespace BJYJ_Admin.Application.System.Services.User;


[ApiDescriptionSettings("System")]
public class SysDeptService : IDynamicApiController, ITransient
{
    public readonly ISqlSugarClient _db;
    public SysDeptService(ISqlSugarClient db)
    {
        _db = db;
    }

    /// <summary>
    ///  获取部门列表                      
    /// </summary>
    /// <returns></returns>
    [DisplayName("获取部门列表")]
    public virtual async Task<PageResult<DeptListOutDto>> GetDeptList([FromQuery] DeptSearchDto input)
    {

        RefAsync<int> totalCount = 0;
        var deptQuery = _db.Queryable<SYS_DEPT>()
                    .WhereIF(!string.IsNullOrWhiteSpace(input.NAME), x => x.NAME.Contains(input.NAME))
                    .WhereIF(!string.IsNullOrWhiteSpace(input.CODE), x => x.CODE.Contains(input.CODE))
                    .WhereIF(input.STATUS.HasValue, x => x.STATUS == input.STATUS)
                    .WhereIF(input.DEPTH.HasValue, x => x.DEPTH == input.DEPTH)
                    .WhereIF(input.PID.HasValue, x => x.PID == input.PID)
                    .OrderBy(x => x.PID, OrderByType.Desc)
                    .OrderBy(x => x.ORDER_NUM, OrderByType.Asc)
                    .Select(outDept => new DeptListOutDto
                    {
                        ID = outDept.ID,
                        NAME = outDept.NAME,
                        CODE = outDept.CODE,
                        ADDRESS = outDept.ADDRESS,
                        PHONE = outDept.PHONE,
                        LXR = outDept.LXR,
                        STATUS = outDept.STATUS,
                        PID = outDept.PID,
                        AREACODE = outDept.AREACODE,
                        AREAID = outDept.AREAID,
                        PARENT_PATH = outDept.PARENT_PATH,
                        DEPTH = outDept.DEPTH,
                        ORDER_NUM = outDept.ORDER_NUM,
                        MEMO = outDept.MEMO

                    });
        // 执行分页查询
        var deptList = await deptQuery.ToPageListAsync(input.page, input.limit, totalCount);

        // 提取当前页所有部门ID
        var deptIds = deptList.Select(x => (int?)x.ID).ToList();

        // 批量查询哪些部门有子节点（使用聚合查询优化性能）
        var hasChildrenList = await _db.Queryable<SYS_DEPT>()
            .Where(x => deptIds.Contains(x.PID))
            .GroupBy(x => x.PID)
            .Select(x => new { PID = x.PID })
            .ToListAsync();

        // 创建快速查找字典
        var hasChildrenDict = hasChildrenList.ToDictionary(x => x.PID, x => true);

        // 给每个角色设置HasChildren属性
        foreach (var dept in deptList)
        {
            dept.HASCHILDREN = hasChildrenDict.ContainsKey(dept.ID);
        }
        return new PageResult<DeptListOutDto>
        {
            page = input.page,
            limit = input.limit,
            totalcount = totalCount,
            data = deptList
        };
    }
    /// <summary>
    /// 新增部门    
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("新增部门")]
    public virtual async Task AddDept(DeptInsertDto input)
    {
        var dept = new SYS_DEPT
        {
            NAME = input.NAME,
            CODE = input.CODE,
            ADDRESS = input.ADDRESS,
            PHONE = input.PHONE,
            LXR = input.LXR,
            STATUS = input.STATUS,
            PID = input.PID,
            PARENT_PATH = input.PARENT_PATH,
            ORDER_NUM = input.ORDER_NUM,
            DEPTH = input.DEPTH,
            AREAID = input.AREAID,
            AREACODE = input.AREACODE,
            AREAIDS = input.AREAIDS,
            AREACODES = input.AREACODES,
            MEMO = input.MEMO,
            CREATE_TIME = DateTime.Now,
            CREATE_BY = App.User?.FindFirstValue("ID")
        };
        await _db.Insertable(dept).ExecuteCommandAsync();
    }
    /// <summary>
    /// 编辑部门
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("编辑部门")]
    public virtual async Task UpdateDept(SYS_DEPT input)
    {
        input.UPDATE_TIME = DateTime.Now;
        input.UPDATE_BY = App.User?.FindFirstValue("ID");
        var result = await _db.Updateable(input)
                .IgnoreColumns(u => new { u.CREATE_BY, u.CREATE_TIME })
                .ExecuteCommandAsync();
        if (result == 0)
            throw Oops.Oh(ErrorCodeEnum.OP0002);
    }
    /// <summary>
    /// 删除部门
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("删除部门及子部门")]
    public virtual async Task DeleteDeptByID([FromQuery] DeptIDDto input)
    {
        // 开启事务处理
        var result = await _db.Ado.UseTranAsync(async () =>
        {
            // 1.查询要删除部门的完整路径
            var dept = await _db.Queryable<SYS_DEPT>().Where(x => x.ID == input.ID).FirstAsync();

            // 2.构建精确的路径匹配条件
            var currentAreaFullPath = $"{dept.PARENT_PATH},{dept.ID}";
            var pathPrefix = currentAreaFullPath + ",";  // 子部门路径前缀
            var directChildPath = currentAreaFullPath;   // 直接子节点路径

            // 3.查询要删除的子部门ID（精确匹配）
            var AreaIds = await _db.Queryable<SYS_DEPT>()
                .Where(x => x.PARENT_PATH.StartsWith(pathPrefix)  // 所有后代
                    || x.PARENT_PATH == directChildPath)          // 直接子节点
                .Select(x => (int?)x.ID)
                .ToListAsync();

            // 4.加入当前角色ID
            AreaIds.Add(input.ID);

            // 5. 删除子部门（使用相同的路径条件）
            await _db.Deleteable<SYS_DEPT>()
                .Where(x => x.PARENT_PATH.StartsWith(pathPrefix)
                    || x.PARENT_PATH == directChildPath)
                .ExecuteCommandAsync();

            // 6. 删除当前部门
            await _db.Deleteable<SYS_DEPT>()
                .Where(x => x.ID == input.ID)
                .ExecuteCommandAsync();

        });
        if (!result.IsSuccess)
            throw Oops.Oh(result.ErrorMessage);

    }

    /// <summary>
    /// 部门详情
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [DisplayName("部门详情")]
    public virtual async Task<SYS_DEPT> GetDeptInfoByID(int id)
    {
        var user = await _db.Queryable<SYS_DEPT>().Where(x => x.ID == id).FirstAsync();
        return user;
    }

    /// <summary>
    /// 启用禁用部门
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisplayName("启用禁用部门")]
    public virtual async Task UpdateStatusByID(DeptStatusDto input)
    {
        var ID = App.User?.FindFirstValue("ID");
        var result = await _db.Updateable<SYS_DEPT>()
                                .SetColumns(it => it.STATUS == input.STATUS)
                                .SetColumns(it => it.UPDATE_TIME == DateTime.Now)
                                .SetColumns(it => it.UPDATE_BY == ID)
                                .Where(it => it.ID == input.ID)
                                .ExecuteCommandAsync();
        if (result == 0)
            throw Oops.Oh(ErrorCodeEnum.OP0000);
    }

}

